﻿package component.tree.web.control;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import component.tree.util.StringUtil;
import component.tree.web.action.ServletHelper;

public class ComponentServlet implements Servlet {
	
	protected static Map paraMap = new HashMap();
	
	private ServletConfig servletConfig;
	
	private static Map methodMap = new HashMap();

	private static Map classMap = new HashMap();
	static{
		classMap.put("tree", "component.tree.web.control.TreeServlet");
	}
	
	public void destroy() {
		paraMap = null;
		servletConfig = null;
	}

	public ServletConfig getServletConfig() {
		// TODO Auto-generated method stub
		return servletConfig;
	}

	public String getServletInfo() {
		// TODO Auto-generated method stub
		return servletConfig.getServletName();
	}

	public void init(ServletConfig config) throws ServletException {
		// TODO Auto-generated method stub
		this.servletConfig = config;
		ServletContext context = config.getServletContext();
		Enumeration myEnum = context.getInitParameterNames();
	     while(myEnum.hasMoreElements()){
	        String name = (String)myEnum.nextElement();//获取参数名
	        String value = context.getInitParameter(name);//获取参数值
	        //System.out.println(name + " = = = = " + value);
	        paraMap.put(name, value);
	     }
	}
	
	public void service(ServletRequest arg0, ServletResponse arg1)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		HttpServletRequest request = (HttpServletRequest)arg0;
		HttpServletResponse response = (HttpServletResponse)arg1;
		ServletHelper helper = new ServletHelper();
		helper.setRequest(request);
		helper.setResponse(response);
		
		//helper.setCache(null,null);//清除缓存
		
		String action = request.getParameter("action");
		if(StringUtil.isNull(action)){
			action = "service";
		}
		
		Class types[] = { ServletHelper.class };
		Object values[] = { helper };
		
		ComponentServlet servlet = null;
		String classNameFlag = request.getParameter("component");
		String className = (String)classMap.get(classNameFlag);
		if(StringUtil.isNull(className)){
			servlet = this;
		}else{
			servlet = (ComponentServlet)getObject(className);
		}
		
		String strForward = (String) performMethod(servlet,action, types, values);
		if(!StringUtil.isNull(strForward)){
			RequestDispatcher reqDispatcher = request.getRequestDispatcher(strForward);
			reqDispatcher.forward(request, response); 
		}
	}

	private Object getObject(String className){
		Class c = null;
		try {
			c = Class.forName(className);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			return c.newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}
	
	//返回methodnName的返回值
	private Object performMethod(Object obj,String methodnName, Class[] types,Object[] values){
		Method method = getMethod(obj,methodnName, types);
		String forward = null;
		if(obj==null) obj = this;
		try {
			//forward = (String) method.invoke(this, values);
			forward = (String) method.invoke(obj, values);
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
		return forward;
	}
	
	private Method getMethod(Object obj,String methodName, Class[] types){
		synchronized (methodMap) {
			Method method = (Method) methodMap.get(methodName);
			Class c = this.getClass();
			if(obj!=null) c = obj.getClass();
			if (method == null) {
				try {
					method = c.getMethod(methodName, types);
				} catch (SecurityException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (NoSuchMethodException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				methodMap.put(methodName, method);
			}
			return method;
		}
	}

}
